#include "stdafx.h"
#include "ThreadReadFile.h"
#include <fstream>
#include <iostream>
#include "DataDefinition.h"
#include "DBFFileProcessor.h"
#include "FixFileProcessor.h"
#include "DateTime.h"
#include "../DzhNewTQSDlg/ConfigInfoInterface.h"
#include <ctime>

using namespace std;

ThreadReadFile::ThreadReadFile(map<int,CircleDequeueBase*> p_mapDBF)
	:m_mapDBF(p_mapDBF)
	,m_mapFileProcessor()
{
}

ThreadReadFile::~ThreadReadFile()
{
	for (unsigned int uiIndex = 0; uiIndex < m_mapFileProcessor.size(); uiIndex++)
	{
		delete m_mapFileProcessor[uiIndex];
	}
}

// Codes below is just for testing
void ThreadReadFile::Run()
{
	// Verify parameters
	if(m_mapDBF.size() == 0)
	{
		LOG(WARNING) << "No elements in the queue. End read file thread";
		return;
	}

	this->InitFileProcessor();

	DateTime clsToday;
	clsToday.SetToCurrentDate();
	while(1)
	{
		if (true == CConfigInfoInterface::Instance()->IsHoliday(DateTime::GetLocalDate()))
		{
			Sleep(1000);
			continue;
		}

		if (false == CConfigInfoInterface::Instance()->IsWeekendWork())
		{
			if (true ==DateTime::IsWeekend())
			{
				Sleep(1000);
				continue;
			}
		}

		if (clsToday.DateToString() != DateTime::GetLocalDate())
		{
			// Get current month and day
			string strMonth;
			string strDay;
			GetMonthDay(strMonth,false,strDay,false);
			string strMonthFilled;
			string strDayFilled;
			GetMonthDay(strMonthFilled,true,strDayFilled,true);

			// Set file path
			FileBase* pclsProcessor = GetProcessor(FILETYPE_GZLX);
			if (NULL == pclsProcessor)
			{
				LOG(WARNING) << "Error to get processor of GZLX";
			}
			else
			{
				string strPath = pclsProcessor->GetFileDir() + "GZLX." + strMonth + strDayFilled;
				pclsProcessor->SetFileFullPath(strPath);
				LOG(INFO) << "Date changed and set to new file path : " << strPath;
			}

			pclsProcessor = GetProcessor(FILETYPE_50ETF);
			if (NULL == pclsProcessor)
			{
				LOG(WARNING) << "Error to get processor of ETF";
			}
			else
			{
				string strPath = pclsProcessor->GetFileDir() + "50__" + strMonthFilled + strDayFilled + ".ETF";
				pclsProcessor->SetFileFullPath(strPath);
				LOG(INFO) << "Date changed and set to new file path : " << strPath;
			}

			pclsProcessor = GetProcessor(FILETYPE_CPXX);
			if (NULL == pclsProcessor)
			{
				LOG(WARNING) << "Error to get processor of CPXX";
			}
			else
			{
				string strPath = pclsProcessor->GetFileDir() + "cpxx" + strMonthFilled + strDayFilled + ".txt";
				pclsProcessor->SetFileFullPath(strPath);
				LOG(INFO) << "Date changed and set to new file path : " << strPath;
			}

			clsToday.SetToCurrentDate();
		}

		// Begin to process file
		map<int,FileBase*>::iterator it = m_mapFileProcessor.begin();
		while(it != m_mapFileProcessor.end())
		{
			it->second->Process();
			it++;
		}

		Sleep(3000);
	}
}

void ThreadReadFile::InitFileProcessor()
{
	// Get current month and day
	string strMonth;
	string strDay;
	GetMonthDay(strMonth,false,strDay,false);
	string strMonthFilled;
	string strDayFilled;
	GetMonthDay(strMonthFilled,true,strDayFilled,true);

	// Get hq information
	vector<HqInfoSet> vecHqInfo = CConfigInfoInterface::Instance()->GetHqInfoSetting();
	for (unsigned int uiIndex = 0; uiIndex < vecHqInfo.size(); uiIndex++)
	{
		if (vecHqInfo[uiIndex].m_bIsChecked == true)
		{
			if (vecHqInfo[uiIndex].m_uiID == FILETYPE_GZLX)
			{
				string strPath = vecHqInfo[uiIndex].m_strPath + "\\GZLX." + strMonth + strDayFilled;
				DBFFileProcessor* pclsGZLX = new DBFFileProcessor(m_mapDBF[FILETYPE_GZLX],0,strPath,vecHqInfo[uiIndex].m_uiMaxLen,false,FILETYPE_GZLX);
				m_mapFileProcessor.insert(make_pair(FILETYPE_GZLX,pclsGZLX));
				continue;
			}
			else if (vecHqInfo[uiIndex].m_uiID == FILETYPE_50ETF)
			{
				string strPath = vecHqInfo[uiIndex].m_strPath + "\\50__" + strMonthFilled + strDayFilled + ".ETF";
				FixFileProcessor* pclsETF = new FixFileProcessor(m_mapDBF[FILETYPE_50ETF],0,strPath,vecHqInfo[uiIndex].m_uiMaxLen,false,FILETYPE_50ETF);
				m_mapFileProcessor.insert(make_pair(FILETYPE_50ETF,pclsETF));
				continue;
			}
			else if (vecHqInfo[uiIndex].m_uiID == FILETYPE_CPXX)
			{
				string strPath = vecHqInfo[uiIndex].m_strPath + "\\cpxx" + strMonthFilled + strDayFilled + ".txt";
				FixFileProcessor* pclsCpxx = new FixFileProcessor(m_mapDBF[FILETYPE_CPXX],0,strPath,vecHqInfo[uiIndex].m_uiMaxLen,false,FILETYPE_CPXX);
				m_mapFileProcessor.insert(make_pair(FILETYPE_CPXX,pclsCpxx));
				continue;
			}
			else
			{
				DBFFileProcessor* pclsProcessor = new DBFFileProcessor(m_mapDBF[vecHqInfo[uiIndex].m_uiID],0,vecHqInfo[uiIndex].m_strPath,vecHqInfo[uiIndex].m_uiMaxLen,false,vecHqInfo[uiIndex].m_uiID);
				m_mapFileProcessor.insert(make_pair(vecHqInfo[uiIndex].m_uiID,pclsProcessor));
			}
		}
	}
}

void ThreadReadFile::GetMonthDay(string &p_strMonth, bool p_bFillBlankMonth, string &p_strDay, bool p_bFillBlankDay)
{
	// Get current year and month
	DateTime clsCurrentDate;
	clsCurrentDate.SetToCurrentDateTime();
	unsigned int uiMonth = clsCurrentDate.GetMonth();
	unsigned int uiDay = clsCurrentDate.GetDay();

	char szMonth[3] = {'\0'};
	char szDay[3] = {'\0'};
	if(true == p_bFillBlankMonth)
	{
		sprintf(szMonth,"%02d",uiMonth);
	}
	else
	{
		sprintf(szMonth,"%d",uiMonth);
	}


	if(true == p_bFillBlankDay)
	{
		sprintf(szDay,"%02d",uiDay);
	}
	else
	{
		sprintf(szDay,"%d",uiDay);
	}

	p_strMonth = szMonth;
	p_strDay = szDay;
}

FileBase* ThreadReadFile::GetProcessor(int p_iProcessorIndex)
{
	map<int,FileBase*>::iterator it = m_mapFileProcessor.begin();
	while(it != m_mapFileProcessor.end())
	{
		if (it->first == p_iProcessorIndex)
		{
			return it->second;
		}

		it++;
	}

	LOG(ERROR) << "Cannot find requested file processor. Index : " << p_iProcessorIndex;
}